
import pylab as p
import math

from bpsk_modular_bits import modular_bits_en_bpsk
from funciones import generar_bits, sumar_ruido_gaussiano_correlacionado, detectar_bayesianamente, sumar_ruido_gaussiano_blanco
from funciones import calcular_estado_markov_estacionario, calcular_estado_markov

N = 1000
alpha_0 = 0
alpha_1 = math.pi
A = 1
L = 8 
sigma2_W = 1
C_W = sigma2_W * p.identity(L)


def generar_y_detectar(modulado_mas_ruido, lambda_01, lambda_11, calcular_P01, P_01=None):
    detectado = []
    error = []
    for i in range(N):
        
        if calcular_P01:
            P_01 = calcular_P01(lambda_01, lambda_11, p.array([1-lambda_01, lambda_01]), i)
            
        detectado_i = detectar_bayesianamente(modulado_mas_ruido[i * L:(i + 1) * L], A, alpha_0, alpha_1, C_W, P_01[0], P_01[1])
        detectado.append(detectado_i[0])
        error.append(detectado_i[1])

    contador = 0
    for i in range(N):
        if (generado[i] != detectado[i]):
            contador += 1       

    errores = contador / float(N)
    return errores


if __name__ == '__main__':
    
    # lambda_01 y lambda_11 diferentes
    lambda_01 = 0.8
    lambda_11 = 0.3
    
    generado = generar_bits(lambda_01, lambda_11, N)
    modulado = modular_bits_en_bpsk(generado, alpha_0, alpha_1, A, L)
    
    modulado_mas_ruido_blanco = sumar_ruido_gaussiano_blanco(modulado, sigma2_W)
    modulado_mas_ruido_correlacionado = sumar_ruido_gaussiano_correlacionado(modulado, sigma2_W)

    error_gaussiano_blanco = generar_y_detectar(modulado_mas_ruido_blanco, lambda_01, lambda_11, calcular_estado_markov)
    error_gaussiano_correlacionado = generar_y_detectar(modulado_mas_ruido_correlacionado, lambda_01, lambda_11, calcular_estado_markov)
    
    print "Error ruido blanco={}".format(error_gaussiano_blanco)
    print "Error ruido correlacionado={}".format(error_gaussiano_correlacionado)

        